﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting.Contexts;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

using Engine.Middlewares;
using Engine.Result;

using Microsoft.CSharp.RuntimeBinder;

using Scheduler;

namespace Engine
{
    public class WaferTesterContext : Scheduler.Context
    {

        public long TestingTime { get; set; }
        public long CycleTime { get; set; }
        public LotResult Result { get; }

        private readonly ThreadLocal<BlockingCollection<object>> _localDutPoint = new ThreadLocal<BlockingCollection<object>>(() => new BlockingCollection<object>(1));
        private ThreadLocal<int> _index = new ThreadLocal<int>(() => -1);
        public TestResultPipe TestResultPipe = new TestResultPipe(5);
        private ThreadLocal<int> _workerId = new ThreadLocal<int>(() => -1);

        public event EventHandler<ChipResult> OnChipResult;//

        public WaferTesterContext()
        {

            Result = new LotResult();
        }

        public void EmitChip(int index)
        {
            var rel = this.Result.NextPass();

            TestResultPipe.AddToBuffer(0, rel);
        }


        public override object Next(object workerId)
        {
            var st = (int)workerId;
            _index.Value++;
            var index = _index.Value;

            //if (st == 0)
            //{
            //    if (Result.NextPass(_index.Value, out var chip))
            //    {
            //        _index.Value++;
            //        Console.WriteLine(string.Join("_", _index.Values.ToArray()));
            //    }
            //    else
            //    {
            //        this.UserCancelled = true;
            //    }  
            //}
            if (index > 5)
            {
                _index.Value = -1;
                return null;
            }

            return index;

        }

        public override bool SkipWorker(object workId)
        {
            throw new NotImplementedException();
        }

        public override object LoadPass(object workerId, EventId eId)
        {
            _workerId.Value = (int)workerId;
            while (!TestResultPipe.HasInBuffer(_workerId.Value))
            {
                Task.Yield();
                Thread.Sleep(0);
                //Console.WriteLine($"饥饿_:{_workerId.Value}");
            }

            var take = TestResultPipe.TryPeek(_workerId.Value, out var dutPoint);

            Console.WriteLine($"开始工作:{_workerId.Value} {dutPoint}");
            //  localDutPoint.Value = dutPoint;
            _localDutPoint.Value.Add(dutPoint);
            return dutPoint;

        }

        private int EedIndex;
        public override object UnloadPass(object workerId, EventId eId, object chip)
        {

            var id = (int)workerId;
            //var b= TestResultPipe.TryDequeue(id, out var dutPoint);

            var item = _localDutPoint.Value.Take();
            if (TestResultPipe.NextWorker(id))
            {
                var value = chip as ChipResult;

                var x = value.Clone();

                while (TestResultPipe.HasInBuffer(id + 1))
                {

                    Thread.Sleep(0);
                }



                TestResultPipe.AddToBuffer(id + 1, x);
                Console.WriteLine($"{_workerId.Value} ->Add Next Work:{id + 1}  {x}");
            }
            else
            {
                EedIndex++;
                Console.WriteLine($"測試結束 {chip} EedIndex: {EedIndex}");
                var value = chip as ChipResult;

                var re = this.Result.GetChipResultById(value.Id);

                OnChipResult?.Invoke(this, re);
            }



            return workerId;


        }

        //public object NextPass(object workerId, EventId eId)
        //{
        //    var id = (int)workerId;
        //    object dutPoint;
        //    while (this.TestResultPipe.TryDequeue(id, out dutPoint))
        //    {
        //        if (UserCancelled)
        //        {
        //            return dutPoint;
        //        }

        //        Task.Yield();
        //    }

        //    return dutPoint;

        //    //if (id==0 && eId==EventId.PassBegin )
        //    //{
        //    //    //TODO 与上料机通知上料
        //    //    Thread.Sleep(1000);//模拟上料
        //    //    if (Result.NextPass(out  var  pChip ))
        //    //    {
        //    //        TestResultPipe.Add(pChip.Chip);
        //    //    }
        //    //    else
        //    //    {
        //    //        UserCancelled = true;
        //    //    }
        //    //}

        //    //if (id != 0 && eId == EventId.PassEnd)
        //    //{
        //    //    TestResultPipe.NextPass((int)workerId, 1);
        //    //}






        //    return new object();
        //}
    }
}
